﻿Public Class LeftBar

	Public Sections As New List(Of Section)
	Public Items As New SortedList(Of String, Section.Item)
	Public MustMeasure As Boolean

	Event TabChanged()

	Sub New()
		InitializeComponent()
		Themes.Register(Me)
		DoubleBuffered = True
	End Sub

	Dim _Active As Rectangle
	Property Active As Rectangle
		Get
			Return _Active
		End Get
		Set(Value As Rectangle)
			If _Active = Value Then Return
			Invalidate(_Active)
			_Active = Value
			Invalidate(_Active)
			Cursor = If(_Active = Nothing, Cursors.Default, Cursors.Hand)
		End Set
	End Property

	Shadows Sub Invalidate(R As Rectangle)
		R.Offset(0, -VerticalScroll.Value)
		MyBase.Invalidate(R)
	End Sub

	Shadows Sub Invalidate()
		MyBase.Invalidate()
	End Sub

	Dim _SelectedItem As String
	Property SelectedItem As String
		Get
			Return _SelectedItem
		End Get
		Set(Value As String)
			_SelectedItem = Value
			Invalidate()
			RaiseEvent TabChanged()
		End Set
	End Property

	Class Section

		Public Text As String
		Public Parent As LeftBar
		Public Expanded As Boolean = True
		Dim RectHeader As Rectangle
		Dim RectClose As Rectangle
		Dim RectSort As Rectangle
		Dim RectExpand As Rectangle

		Dim Rects As New List(Of Rectangle)

		Sub Measure(ByRef y As Integer, w As Integer)
			Rects.Clear()
			RectClose = Nothing
			RectSort = Nothing
			If Text <> "" Then
				RectHeader = New Rectangle(0, y, w - 0, 20)
				RectExpand = New Rectangle(0, y, RectHeader.Height, RectHeader.Height)
				Rects.Add(RectHeader)
				y += RectHeader.Height
				RectSort = New Rectangle(RectHeader.Right - RectHeader.Height + 1, RectHeader.Top + 1, RectHeader.Height - 2, RectHeader.Height - 2)
				Rects.Add(RectSort)
			End If
			If Expanded Then
				Dim A() As Item = Items.ToArray
				For i = 0 To A.Length - 1
					Dim Item As Item = A(i)
					Item.Measure(y, w)
					Rects.Add(Item.Rect)
				Next
			End If
			y += 1
		End Sub

		Sub Draw(g As Graphics)
			Dim R As New Rectangle(Rects(0).Left, Rects(0).Top, Rects(0).Width, Rects(Rects.Count - 1).Bottom - Rects(0).Top + 2)
			R.Inflate(-2, -2)
			g.PixelOffsetMode = Drawing2D.PixelOffsetMode.None
			g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
			If Text <> "" Then
				R = RectHeader
				'g.FillRectangle(New SolidBrush(Color.FromArgb(128, Color.Black)), R)
				g.SmoothingMode = Drawing2D.SmoothingMode.None
				g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
				R.Offset(RectExpand.Width - 2, 0)
				R.Width -= RectExpand.Width - 2
				R.Inflate(-2, -2)

				Dim tw = g.MeasureString(Text, Parent.Font).Width
				DrawStringLighted(g, Text, Parent.Font, Color.FromArgb(96, 0, 0), R, StrFormat("lm"))
				g.SmoothingMode = Drawing2D.SmoothingMode.None
				'G.DrawLine(New Pen(Color.FromArgb(32, Color.Black)), R.Left, R.Top + R.Height \ 2 + 1, TextRect.Left - 4, R.Top + R.Height \ 2 + 1)
				g.DrawLine(New Pen(Color.FromArgb(32, Color.Black)), R.Left + tw, R.Top + R.Height \ 2 + 1, R.Right - 2, R.Top + R.Height \ 2 + 1)
				g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
				R = RectSort
				R.Inflate(-2, -2)
				R.Inflate(-2, -2)
				'DrawImage(g, My.Resources.sort, R)
				R = RectExpand
				R.Inflate(-2, -2)
				Dim Path As New Drawing2D.GraphicsPath
				If Expanded Then
					R.Inflate(-4, -5)
					Path.AddLines(New Point() {New Point(R.Left, R.Top), New Point(R.Right, R.Top), New Point(R.Left + R.Width / 2, R.Bottom)})
				Else
					R.Inflate(-5, -4)
					Path.AddLines(New Point() {New Point(R.Left, R.Top), New Point(R.Right, R.Top + R.Height / 2), New Point(R.Left, R.Bottom)})
				End If
				g.FillPath(New SolidBrush(Color.FromArgb(If(RectExpand = Parent.Active, 255, 192), Color.Black)), Path)
			End If
			If Expanded Then
				For Each Item In Items
					Item.Draw(g)
				Next
			End If
		End Sub

		Dim Items As New List(Of Item)

		Class Item

			Public Rect As Rectangle
			Public RectCheck As Rectangle
			Public Display As String
			Public Section As Section
			Public Key As String

			Sub New(Section As Section, Display As String, Key As String)
				Me.Section = Section
				Me.Display = Display
				Me.Key = Key
			End Sub

			Sub Measure(ByRef y As Integer, w As Integer)
				Rect = New Rectangle(2, y, w - 7, 20)
				RectCheck = New Rectangle(Rect.Left, Rect.Top, Rect.Height, Rect.Height)
				y += Rect.Height + 1
			End Sub

			Sub Draw(g As Graphics)
				Dim col As Color = Color.DarkRed
				Dim R As Rectangle = Rect
				Renderer.PaintButton(g, R, Nothing, False, Rect = Section.Parent.Active, Section.Parent.SelectedItem = Key, Not Disabled)
				g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
				R = RectCheck
				R.Inflate(-6, -6)
				g.DrawEllipse(New Pen(Color.FromArgb(If(Disabled, 64, If(Rect = Section.Parent.Active, 192, 160)), Color.Black)), R)
				g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
				If Section.Parent.SelectedItem = Key Then
					g.FillEllipse(New SolidBrush(Color.FromArgb(If(Disabled, 64, If(Rect = Section.Parent.Active, 192, 160)), Color.Black)), R)
				End If
				R = Rect
				R.Offset(RectCheck.Width, 0)
				R.Width -= RectCheck.Width
				Dim Text As String = Me.Display
				Dim w = g.MeasureString(Text, Themes.Current.Font).Width
				If R.Left + w > R.Width - 12 Then w = R.Width - 12 - R.Left
				Dim F As StringFormat = StrFormat("lm")
				F.Trimming = StringTrimming.EllipsisWord
				g.DrawString(Text, Themes.Current.Font, New SolidBrush(Color.FromArgb(If(Disabled, 128, 255), Themes.Current.LabelColor)), R, F)
			End Sub

			Dim _Disabled As Boolean
			Property Disabled As Boolean
				Get
					Return _Disabled
				End Get
				Set(Value As Boolean)
					_Disabled = Value
					Section.Parent.Invalidate(Rect)
				End Set
			End Property

			ReadOnly Property Active As Boolean
				Get
					Return Section.Parent.Active = Rect
				End Get
			End Property

			Function MouseMove(p As Point, Clicked As Boolean) As Boolean
				If Disabled Then Return False
				If Not Rect.Contains(p) Then Return False
				If Not Clicked Then
					Section.Parent.Active = Rect
				Else
					Section.Parent.SelectedItem = Key
				End If
				Return True
			End Function

		End Class

		Sub SetConversions(Text As String)
			For Each Item As String In Text.Split(",")
				Dim Data = Item.Split(":")
				Conversions.Add(Data(0), Data(1))
			Next
		End Sub

		Dim Conversions As New SortedList(Of String, String)

		Function MouseMove(p As Point, Clicked As Boolean) As Boolean
			If Clicked Then
				If RectExpand.Contains(p) Then If Clicked Then Expanded = Not Expanded : Parent.MustMeasure = True : Parent.Invalidate() : Return True
			Else
				If RectExpand.Contains(p) Then Parent.Active = RectExpand : Return True
				If RectSort.Contains(p) Then Parent.Active = RectSort : Return True
			End If
			If Expanded Then
				For Each Item As Item In Items
					If Item.MouseMove(p, Clicked) Then Return True
				Next
			End If
		End Function

		Function AddItem(Display As String, Key As String) As Item
			Dim Item As New Item(Me, Display, Key)
			Items.Add(Item)
			Return Item
		End Function

	End Class

	Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
		If MustMeasure Then Measure()
		Dim R As Rectangle = ClientRectangle
		e.Graphics.FillRectangle(Themes.Current.FormColor.Mix(Color.White, 50).Brush, R)
		e.Graphics.TranslateTransform(0, AutoScrollPosition.Y)
		e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
		e.Graphics.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
		e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
		For Each Item As Section In Sections
			Item.Draw(e.Graphics)
		Next
		e.Graphics.ResetTransform()
		e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.None
		e.Graphics.PixelOffsetMode = Drawing2D.PixelOffsetMode.None
		e.Graphics.DrawLine(New Pen(Color.FromArgb(64, Color.Black)), R.Right - 1, R.Top, R.Right - 1, R.Bottom)
	End Sub

	Protected Overrides Sub OnResize(e As System.EventArgs)
		MyBase.OnResize(e)
		MustMeasure = True
		Invalidate()
	End Sub

	Dim Header As Rectangle

	Sub Measure()
		MustMeasure = False
		Dim w As Integer = ClientRectangle.Width
		Dim y As Integer = 4
		For Each Item As Section In Sections
			Item.Measure(y, w)
		Next
		AutoScrollMinSize = New Size(0, y)
	End Sub

	Protected Overrides Sub OnMouseLeave(e As System.EventArgs)
		MyBase.OnMouseLeave(e)
		Active = Nothing
	End Sub

	Protected Overrides Sub OnMouseWheel(e As System.Windows.Forms.MouseEventArgs)
		If Not ClientRectangle.Contains(e.Location) Then Return
		MyBase.OnMouseWheel(e)
	End Sub

	Protected Overrides Sub OnMouseMove(e As System.Windows.Forms.MouseEventArgs)
		MyBase.OnMouseMove(e)
		Dim P = e.Location
		P.Offset(0, VerticalScroll.Value)
		For Each Item As Section In Sections
			If Item.MouseMove(P, False) Then Return
		Next
		Active = Nothing
	End Sub

	Protected Overrides Sub OnMouseDown(e As System.Windows.Forms.MouseEventArgs)
		MyBase.OnMouseDown(e)
		Dim P As Point = e.Location
		P.Offset(0, -AutoScrollPosition.Y)
		For Each Item As Section In Sections
			If Item.MouseMove(P, True) Then Return
		Next
		Active = Nothing
	End Sub

	Sub Restart()
		CType(Parent, Report).Restart()
	End Sub

	Sub Reset()
		For Each Item In Items.Values
			Item.Disabled = False
		Next
	End Sub

	Dim Where As String = ""

	'Protected Overrides Sub OnScroll(se As System.Windows.Forms.ScrollEventArgs)
	'	MyBase.OnScroll(se)
	'	Invalidate()
	'End Sub

	Sub Clear()
		Sections.Clear()
		MustMeasure = True
		MyBase.Invalidate()
	End Sub

	Dim CurrentSection As Section

	Sub AddSection(Text As String)
		Dim Section As New Section
		Section.Parent = Me
		Section.Text = Text
		Sections.Add(Section)
		CurrentSection = Section
	End Sub

	Sub AddItem(Display As String, Key As String)
		If CurrentSection Is Nothing Then AddSection("")
		Dim Item = CurrentSection.AddItem(Display, Key)
		Items.Add(Key, Item)
	End Sub

	Sub DisableItem(Item As String)
		Items(Item).Disabled = True
	End Sub

End Class
